package org.vaadin.html5dropzone.widgetset.client.ui;

import com.google.gwt.user.client.Element;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.ui.VCssLayout;

public class VHtml5DropZone extends VCssLayout {
	public enum DataFlawor {
		TEXT, FILE_CONTENTS_TEXT
	}

	/** Set the CSS class name to allow styling. */
	public static final String CLASSNAME = "v-html5dropzone";

	private static final String DRAG_OVER_STYLE = CLASSNAME + "-active";

	/** The client side widget identifier */
	protected String paintableId;

	/** Reference to the server connection object. */
	ApplicationConnection client;

	public VHtml5DropZone() {
		super();
		setStyleName(CLASSNAME);
		hookListeners(getElement());
	}

	@Override
	protected void onAttach() {
		super.onAttach();
	}
	
	@Override
	public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
		this.client = client;
		this.paintableId = uidl.getId();
		super.updateFromUIDL(uidl, client);
	}

	/** 
	 * Hooks html5 dnd listeners.
	 * 
	 * @param el
	 */
	private native void hookListeners(Element el)
	/*-{

	    var me = this;
	    
	    if(el.addEventListener) {
	        el.addEventListener("dragenter",  function(ev) {
		        return me.@org.vaadin.html5dropzone.widgetset.client.ui.VHtml5DropZone::onHtml5DragEnter(Lorg/vaadin/html5dropzone/widgetset/client/ui/Html5DragEvent;)(ev);
	        }, false);
	        
	        el.addEventListener("dragleave",  function(ev) {
		        return me.@org.vaadin.html5dropzone.widgetset.client.ui.VHtml5DropZone::onHtml5DragLeave(Lorg/vaadin/html5dropzone/widgetset/client/ui/Html5DragEvent;)(ev);
	        }, false);
	
	        el.addEventListener("dragover",  function(ev) {
		        return me.@org.vaadin.html5dropzone.widgetset.client.ui.VHtml5DropZone::onHtml5DragOver(Lorg/vaadin/html5dropzone/widgetset/client/ui/Html5DragEvent;)(ev);
	        }, false);
	
	        el.addEventListener("drop",  function(ev) {
		        return me.@org.vaadin.html5dropzone.widgetset.client.ui.VHtml5DropZone::onHtml5Drop(Lorg/vaadin/html5dropzone/widgetset/client/ui/Html5DragEvent;)(ev);
	        }, false);
	    
	    } else {
	        el.attachEvent("ondragenter",  function(ev) {
		        return me.@org.vaadin.html5dropzone.widgetset.client.ui.VHtml5DropZone::onHtml5DragEnter(Lorg/vaadin/html5dropzone/widgetset/client/ui/Html5DragEvent;)(ev);
	        });
	        
	        el.attachEvent("ondragleave",  function(ev) {
		        return me.@org.vaadin.html5dropzone.widgetset.client.ui.VHtml5DropZone::onHtml5DragLeave(Lorg/vaadin/html5dropzone/widgetset/client/ui/Html5DragEvent;)(ev);
	        });
	
	        el.attachEvent("ondragover",  function(ev) {
		        return me.@org.vaadin.html5dropzone.widgetset.client.ui.VHtml5DropZone::onHtml5DragOver(Lorg/vaadin/html5dropzone/widgetset/client/ui/Html5DragEvent;)(ev);
	        });
	
	        el.attachEvent("ondrop",  function(ev) {
		        return me.@org.vaadin.html5dropzone.widgetset.client.ui.VHtml5DropZone::onHtml5Drop(Lorg/vaadin/html5dropzone/widgetset/client/ui/Html5DragEvent;)(ev);
	        });
	    }
	    
	}-*/;

	@SuppressWarnings("unused")
	protected boolean onHtml5Drop(Html5DragEvent event) {
		ApplicationConnection.getConsole().log("drag drop");
		String dataAsText = event.getDataAsText("Text");
		if(dataAsText != null) {
			client.updateVariable(paintableId, DataFlawor.TEXT.toString(),
					dataAsText, false);
		}
		
		String fileAsString = event.getFileAsBase64String(0);
		
		if(fileAsString != null) {
			client.updateVariable(paintableId, DataFlawor.FILE_CONTENTS_TEXT
					.toString(), fileAsString, false);
		}

		client.sendPendingVariableChanges();
		setStyleName(getElement(), DRAG_OVER_STYLE, false);
		event.preventDefault();
		event.stopPropagation();
		return false;
	}

	@SuppressWarnings("unused")
	protected boolean onHtml5DragOver(Html5DragEvent event) {
		ApplicationConnection.getConsole().log("drag over");
		if (BrowserInfo.get().isSafari())
			event.setDragEffect("copy");
		event.preventDefault();
		event.stopPropagation();
		return false;
	}

	@SuppressWarnings("unused")
	protected boolean onHtml5DragEnter(Html5DragEvent event) {
		ApplicationConnection.getConsole().log("drag enter");
		setStyleName(getElement(), DRAG_OVER_STYLE, true);
		event.preventDefault();
		event.stopPropagation();
		return false;
	}

	@SuppressWarnings("unused")
	protected boolean onHtml5DragLeave(Html5DragEvent event) {
		ApplicationConnection.getConsole().log("drag leave");
		setStyleName(getElement(), DRAG_OVER_STYLE, false);
		event.preventDefault();
		event.stopPropagation();
		return false;
	}

}
